﻿using FreeDream.Common;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.WebSockets;
using System.Text;
using System.Threading.Tasks;

namespace FreeDream.Infrastructure
{
    public class WebSocketMiddleware
    {
        private readonly RequestDelegate _next;
        private WebSocketConnectionManager _webSocketConnectionManager { get; set; }
        private WebSocketHandler _webSocketHandler { get; set; }

        public WebSocketMiddleware(
            RequestDelegate next,
            WebSocketConnectionManager webSocketConnectionManager,
            WebSocketHandler WebSocketHandler)
        {
            _next = next;
            _webSocketConnectionManager = webSocketConnectionManager;
            _webSocketHandler = WebSocketHandler;
        }

        public async Task Invoke(HttpContext httpContext)
        {
            if (httpContext.WebSockets.IsWebSocketRequest)
            {
                var cancellationToken = httpContext.RequestAborted;
                var currentWebSocket = await httpContext.WebSockets.AcceptWebSocketAsync();
                _webSocketConnectionManager.AddSocket(currentWebSocket);

                while (true)
                {
                    if (cancellationToken.IsCancellationRequested) break;
                    var response = await _webSocketHandler.ReceiveMessageAsync(currentWebSocket, cancellationToken);

                    if (string.IsNullOrEmpty(response) && currentWebSocket.State != WebSocketState.Open) break;

                    foreach (var item in _webSocketConnectionManager.GetAll())
                    {
                        if (item.Value.State == WebSocketState.Open)
                        {
                            await _webSocketHandler.SendMessageAsync(item.Value, response, cancellationToken);
                        }
                        continue;
                    }
                }

                await _webSocketConnectionManager.RemoveSocket(currentWebSocket);
            }
            else
            {
                await _next(httpContext);
            }
        }


        #region JS

        //   <script>
        //       $(function () {
        //           var protocol = location.protocol === "https:" ? "wss:" : "ws:";
        //           var Uri = protocol + "//" + window.location.host + "/ws";
        //           var socket = new WebSocket(Uri);
        //           socket.onopen = e => {
        //               console.log("socket opened", e);
        //           };

        //       socket.onclose = function(e)
        //       {
        //           console.log("socket closed", e);
        //       };

        //       //function to receive from server.
        //       socket.onmessage = function(e)
        //       {
        //           console.log("Message:" + e.data);
        //               $('#msgs').append(e.data + '<br />');
        //       };

        //       socket.onerror = function(e)
        //       {
        //           console.error(e.data);
        //       };
        //   });
        //</ script >

        #endregion
    }
}
